package cn.touna.jss.modules.third.xinyan;

import cn.touna.risk.api.enums.SystemErrorCodeEnum;
import cn.touna.jss.common.properties.disconf.XinyanProperties;
import cn.touna.jss.common.util.DateUtils;
import cn.touna.jss.modules.adapter.ApiMapping;
import cn.touna.jss.modules.third.xinyan.constant.XinyanConstant;
import cn.touna.jss.modules.third.xinyan.dto.XinyanRequest;
import cn.touna.jss.modules.third.xinyan.util.JXMConvertUtil;
import cn.touna.jss.modules.third.xinyan.util.RsaCodingUtil;
import cn.touna.risk.api.domain.Response;
import cn.touna.risk.api.utils.ServiceContext;
import com.alibaba.fastjson.JSON;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.HashMap;
import java.util.Map;

/**
 ********************************************************
 * 新颜api实现
 * @author zhangjialian
 * @Date 2018-08-14 15:47
 * @Version V1.0
 ********************************************************/
@Service
public class XinyanService {
    private Logger log= LogManager.getLogger(XinyanService.class);
    @Autowired
    private XinyanProperties xinyanProperties;
    @Resource(name = "httpsRestTemplate")
    private RestTemplate restTemplate;

    @ApiMapping(value = "xinyan.negativeBlack",desc = "新颜.负面拉黑查询")
    public Response getNegativeBlackInfo(XinyanRequest req, HttpServletRequest request) throws Exception {
        log.info("负面拉黑信息新颜接口(getNegativeBlackInfo)调用 begin:"+req.toString());
        String msg=checkNegativeBlackReq(req);
        if(StringUtils.isNotEmpty(msg)){return new Response().fail(SystemErrorCodeEnum.JSS_PARAM_CHECK_FAILED.getErrorCode(),msg);}
        String pfxPath=checkPfxFile();
        if(StringUtils.isEmpty(pfxPath)) {return new Response().fail(SystemErrorCodeEnum.JSS_SYSTEM_ERROR.getErrorCode(),"检测发现新颜私钥文件不存在");}
        MultiValueMap<String, Object> params = getRequestParams(req,pfxPath);
        log.info("负面拉黑组装请求参数:"+params.toString());
        //发送新颜获取负面拉黑信息
        HttpHeaders requestHeaders = new HttpHeaders();
        String result=restTemplate.postForObject(xinyanProperties.getWashblackUrl(),
                new HttpEntity(params,requestHeaders),String.class);
        log.info(String.format("负面拉黑信息地址:%s,新颜返回结果:%s",xinyanProperties.getWashblackUrl(),result));
        return parseResult(result);
    }


    /**
     ********************************************************************
     * 解析返回的负面拉黑结果信息
     * @param result 负面拉黑结果字符串
     * @Author  zhangjialian
     * @return  cn.touna.risk.api.domain.Response
     * @date    2018/8/15 10:02
     ********************************************************************/
    private Response parseResult(String result) {
        Response response=new Response();
        if (StringUtils.isEmpty(result)){
            log.error("检测发现新颜返回结果为空！");
            return response.fail(SystemErrorCodeEnum.JSS_EXTSYSTEM_RESP_FAIL.getErrorCode(),"返回结果为空");
        }
        if (XinyanConstant.DEFAULT_INDUSTRY_TYPE.equals("xml")) {
            result = JXMConvertUtil.XmlConvertJson(result);
        }

        response.setData(JSON.parseObject(result));
        return response.success();
    }
    /**
     ********************************************************************
     * 组装负面拉黑请求参数
     * @param request 请求对象
     * @param pfxPath pfx文件路径
     * @Author  zhangjialian
     * @return  org.springframework.utils.MultiValueMap<java.lang.String,java.lang.Object>
     * @date    2018/8/16 10:35
     ********************************************************************/
    private MultiValueMap<String, Object> getRequestParams(XinyanRequest request, String pfxPath) throws Exception{
        MultiValueMap<String, Object> params=new LinkedMultiValueMap<>();
        params.add("member_id", xinyanProperties.getMemberId());
        params.add("terminal_id", xinyanProperties.getTerminalId());
        params.add("data_content", getReqData(request,pfxPath));
        params.add("data_type", XinyanConstant.DEFAULT_DATE_TYPE);
        return params;
    }
    /**
     ********************************************************************
     * 根据私钥文件组装加密数据
     * @param request 请求对象
     * @param pfxPath pfx文件路径
     * @Author  zhangjialian
     * @return  java.lang.String
     * @date    2018/8/16 10:34
     ********************************************************************/
    private String getReqData(XinyanRequest request,String pfxPath) throws Exception {
        Map<String, Object> data = new HashMap();
        data.put("member_id", xinyanProperties.getMemberId());
        data.put("terminal_id", xinyanProperties.getTerminalId());
        data.put("trans_id", ServiceContext.genUniqueId());
        data.put("trade_date", DateUtils.getCurrentLocal2());//yyyyMMddHHmmss
        data.put("versions", XinyanConstant.VERSION);
        data.put("phone_no", request.getMobile());
        data.put("bankcard_no", request.getBankCardNo());
        data.put("id_no", request.getIdCard());
        data.put("id_name", request.getName());
        data.put("industry_type", XinyanConstant.DEFAULT_INDUSTRY_TYPE);
        String params=JSON.toJSONString(data);
        String base64Str=new String(new Base64().encode(params.getBytes("UTF-8")));
        return RsaCodingUtil.encryptByPriPfxFile(base64Str, pfxPath, xinyanProperties.getPfxPwd());
    }
    /**
     ********************************************************************
     * 检查新颜负面拉黑入参
     * @param req 请求对象
     * @Author  zhangjialian
     * @return  java.lang.String
     * @date    2018/8/16 10:26
     ********************************************************************/
    private String checkNegativeBlackReq(XinyanRequest req) {
        if(req==null){
            return "新颜负面拉黑请求对象不能为空";
        }else if(StringUtils.isEmpty(req.getIdCard())){
            return "身份证号不能为空";
        }else if(StringUtils.isEmpty(req.getName())){
            return "姓名不能为空";
        }
        return null;
    }
    /**
     * 每次请求检查公钥文件是否存在
     */
    private String checkPfxFile() {
        String pfxClassPath=xinyanProperties.getCertPath()
                +File.separator+ xinyanProperties.getPfxName();
        File pfxFile = new File(pfxClassPath);
        if (!pfxFile.exists()) {
            log.error("检测发现新颜私钥文件不存在,"+pfxClassPath);
            return null;
        }else{
            return pfxFile.getPath();
        }
    }
    /*private String checkPfxFile() {
        File pfxFile = null;
        String pfxClassPath=ResourceUtils.CLASSPATH_URL_PREFIX+ XinyanConstant.CERT_PATH
                +File.separator+ xinyanProperties.getPfxName();
        try {
            pfxFile = ResourceUtils.getFile(pfxClassPath);
            if (!pfxFile.exists()) {
                log.error("检测发现新颜私钥文件不存在,"+pfxClassPath);
            }
            return pfxFile.getPath();
        } catch (FileNotFoundException e) {
            log.error("检测发现新颜私钥文件不存在,"+pfxClassPath,e);
        }
        return null;
    }*/
}
